//
//  PFMessageHUD.m
//  PetsCare
//
//  Created by Latsen on 2018/7/2.
//  Copyright © 2018年 Latsen. All rights reserved.
//

#import "PFMessageHUD.h"
#import "Masonry.h"
#import "NSString+Size.h"
#import "UIViewAdditions.h"


static PFMessageConfig *instance = nil;
@implementation PFMessageConfig

+ (instancetype)config{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[PFMessageConfig alloc] init];
    });
    return instance;
}

- (id)init{
    if (self = [super init]) {
        _animationType = PFAnimationTypePop;
        _stayType = HUDStayTypeAuto;
        _autoDismissTime = 2.8;
        
        _ftopSpace = 5;
        _fbottomSpace = 5;
        _fleftSpace = 10;
        _frightSpace = 10;
    }
    return self;
}

@end


@interface PFMessageHUD ()

@property (nonatomic, assign) PFAnimationType animationType;

@property (nonatomic, assign) NSTimeInterval delayTime;

@property (nonatomic, assign) HUDStayType stayType;

/** view高度 可能会根据文字调整 Default 35 */
@property (nonatomic, assign) CGFloat viewHeight;
/** 内容view */
@property (nonatomic, strong) UIView *contentView;
/** 扩展 - icon */
@property (nonatomic, strong) UIImageView *iconImageView;
/** 内容 */
@property (nonatomic, strong) UILabel *textLabel;


@property (nonatomic, strong) NSMutableArray <PFMSGObject *> *MsgObjs;

/** 右侧按钮 */
@property (nonatomic, strong) UIButton *rightButton;
@property (nonatomic, assign) BOOL enablRightClick;

@property (nonatomic, strong) NSTimer *autoDismissTimer;
@property (nonatomic, assign, getter=hasFinished) BOOL finished;


@end

#define defaultDelayTime        [[PFMessageConfig config] autoDismissTime]
#define defaultAnimationType    [[PFMessageConfig config] animationType]
#define defaultStayType         [[PFMessageConfig config] stayType]

#define topSpace                [[PFMessageConfig config] ftopSpace]
#define bottomSpace             [[PFMessageConfig config] fbottomSpace]
#define leftSpace               [[PFMessageConfig config] fleftSpace]
#define rightSpace              [[PFMessageConfig config] frightSpace]


@implementation PFMessageHUD

/** Default stayType = auto */
+ (BOOL)showMessage:(NSString *)text inView:(UIView *)view animated:(PFAnimationType)animated{
    return [self showMessage:(NSString *)text inView:view animated:animated stayType:defaultStayType afterDelay:defaultDelayTime];
}

/** Default stayType = auto */
+ (BOOL)showError:(NSString *)text inView:(UIView *)view animated:(PFAnimationType)animatied needClick:(BOOL)needClick{
    NSTimeInterval delay = 0;
    HUDStayType stayType = HUDStayTypeErrorWithClickIcon;
    if (!needClick) {
        delay = defaultDelayTime;
        stayType = HUDStayTypeAuto;
    }
    return [self showMessage:(NSString *)text inView:view animated:animatied stayType:stayType afterDelay:delay];
}

/** 扩展以后区分 info,succ,error 状态hud */
+ (BOOL)showSuccess:(NSString *)text inView:(UIView *)view animated:(PFAnimationType)animatied{
    return [self showMessage:(NSString *)text inView:view animated:animatied stayType:defaultStayType afterDelay:defaultDelayTime];
}

/** Default stayType = auto */
+ (BOOL)showMessage:(NSString *)text inView:(UIView *)view stayType:(HUDStayType)type{
    NSTimeInterval delay = defaultDelayTime;
    if (type == HUDStayTypeErrorWithClickIcon || type == HUDStayTypeErrorWithClickIcon) {
        delay = 0;
    }
    return [self showMessage:(NSString *)text inView:view animated:defaultAnimationType stayType:type afterDelay:delay];
}

/** Default stayType = auto */
+ (BOOL)showError:(NSString *)text inView:(UIView *)view stayType:(HUDStayType)type{
    NSTimeInterval delay = defaultDelayTime;
    if (type == HUDStayTypeErrorWithClickIcon || type == HUDStayTypeNetworkError) {
        delay = 0;
    }
    return [self showMessage:(NSString *)text inView:view animated:defaultAnimationType stayType:type afterDelay:delay];
}

/** 扩展以后区分 info,succ,error 状态hud */
+ (BOOL)showSuccess:(NSString *)text inView:(UIView *)view stayType:(HUDStayType)type{
    NSTimeInterval delay = defaultDelayTime;
    if (type == HUDStayTypeErrorWithClickIcon || type == HUDStayTypeNetworkError) {
        delay = 0;
    }
    return [self showMessage:(NSString *)text inView:view animated:defaultAnimationType stayType:type afterDelay:delay];
}

#pragma mark - Show Message
/** all */
+ (BOOL)showMessage:(NSString *)text inView:(UIView *)view animated:(PFAnimationType)animated stayType:(HUDStayType)type afterDelay:(NSTimeInterval)delay{
    if (!view) view = [self getViewFromNormalWindow];
    
    [self hideHUDInView:view];
    PFMessageHUD *hud = [[PFMessageHUD alloc] init];
    hud.animationType = animated;
    hud.stayType = type;
    
    if (view) {
        [hud.textLabel setText:text];
        [view addSubview:hud];
        [hud showAnimated:YES];
        [hud hideAnimated:YES afterDelay:delay];
        return YES;
    }
    return NO;
}

+ (BOOL)hideHUDInView:(UIView *)view{
    PFMessageHUD *hud = [self HUDInView:view];
    if (hud) {
        [hud hideAnimated:YES];
    }
    return YES;
}

- (void)showAnimated:(BOOL)animate{
    
    self.enablRightClick = NO;
    if (self.stayType == HUDStayTypeErrorWithClickIcon || self.stayType == HUDStayTypeNetworkError) {
        self.contentView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.7];
        self.textLabel.textColor = [UIColor whiteColor];
        if (self.stayType == HUDStayTypeErrorWithClickIcon) {
            self.enablRightClick = YES;
        }
    }else{
        self.contentView.backgroundColor = [[UIColor darkGrayColor] colorWithAlphaComponent:0.7];
        self.textLabel.textColor = [UIColor whiteColor];
    }
    
    CGRect frame = CGRectMake(0, 0, SCREEN_WIDTH, self.viewHeight);
    UIViewController *controller = GetViewControllerOfView(self);
    if (controller.navigationController) {
        if (controller.navigationController.navigationBarHidden) {
            frame.origin.y = STATUS_BAR_HEIGHT;
        }else{
            frame.origin.y = 0;
        }
    }else if ([self.superview isKindOfClass:[UIWindow class]]){
        UIViewController *rootVc = GetViewControllerOfWindow();
        if (rootVc.navigationController.navigationBarHidden) {
            //无
            frame.origin.y = STATUS_BAR_HEIGHT;
        }else{
            frame.origin.y = STATUS_NAVI_HEIGHT;
        }
    }
    [self setFrame:frame];
    
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_offset(-self.viewHeight);
    }];
    [self layoutIfNeeded];
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_offset(0);
    }];
    
    [UIView animateWithDuration:0.3 animations:^{
        [self layoutIfNeeded];
    }];
}

- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay{
    if (delay <= 0) {
        return;
    }
    if (!_autoDismissTimer) {
        NSTimer *timer = [NSTimer timerWithTimeInterval:_delayTime target:self selector:@selector(dismissTimer:) userInfo:nil repeats:NO];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:(NSRunLoopCommonModes)];
        self.autoDismissTimer = timer;
    }else{
        [self.autoDismissTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:_delayTime]];
    }
}
- (void)dismissTimer:(NSTimer *)timer{
    [self hideAnimated:YES];
}

- (void)hideAnimated:(BOOL)animated{
    if ([self.autoDismissTimer isValid]) {
        [self.autoDismissTimer invalidate];
    }
    self.autoDismissTimer = nil;
    self.finished = YES;
    
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_offset(-self.viewHeight);
    }];
    [UIView animateWithDuration:0.3 animations:^{
        [self layoutIfNeeded];
    } completion:^(BOOL finished) {
        [self removeFromSuperview];
    }];
}


+ (PFMessageHUD *)HUDInView:(UIView *)view{
    NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];
    for (UIView *subview in subviewsEnum) {
        if ([subview isKindOfClass:self]) {
            return (PFMessageHUD *)subview;
        }
    }
    return nil;
}

- (CGFloat)viewHeight{
    NSString *text = self.textLabel.text;
    CGSize size = [text tt_sizeWithFont:_textLabel.font constrainedToWidth:_textLabel.width];
    if (size.height + topSpace + bottomSpace >35) {
        return 50;
    }
    return 35;
}

#pragma mark - Events
//右侧按钮点击
- (void)rightButtonClick:(id)sender{
    [self hideAnimated:YES];
}

#pragma mark - View init
- (instancetype)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super initWithCoder:aDecoder])) {
        [self commonInit];
    }
    return self;
}

- (void)setEnablRightClick:(BOOL)enablRightClick{
    _enablRightClick = enablRightClick;
    if (enablRightClick) {
        //right = -10, width = 20, height = 30;
        [self.rightButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.right.mas_offset(-10);
        }];
        [self.rightButton setHidden:NO];
    }else{
        [self.rightButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.right.mas_offset(10);
        }];
        [self.rightButton setHidden:YES];
    }
}
- (void)commonInit{
    //default value
    self.delayTime = defaultDelayTime;
    self.animationType = defaultAnimationType;
    self.stayType = defaultStayType;
    
    self.clipsToBounds = YES;
    
    self.contentView = [[UIView alloc] init];
    self.contentView.clipsToBounds = YES;
    self.contentView.backgroundColor = PFRGBColor(235,235 , 235);
    
    self.iconImageView = [[UIImageView alloc] init];
    
    self.textLabel = [[UILabel alloc] init];
    _textLabel.textAlignment = NSTextAlignmentCenter;
    _textLabel.font = [UIFont systemFontOfSize:15.0];
    _textLabel.textColor = [UIColor darkGrayColor];
    _textLabel.numberOfLines = 0;
    
    self.rightButton = [UIButton buttonWithType:(UIButtonTypeSystem)];
    _rightButton.tintColor = [UIColor whiteColor];
    
    [self addSubview:self.contentView];
    [self.contentView addSubviews:@[_iconImageView,_textLabel,_rightButton]];
    
    //hiden left = 10, width = 18
    [self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_offset(8);
        make.centerY.mas_offset(0);
        make.width.and.height.mas_equalTo(0);
    }];
    
    [self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self.iconImageView.mas_right).offset(5);
        make.right.mas_equalTo(self.rightButton.mas_left).offset(-5);
        make.centerY.mas_offset(0);
    }];
    
    [self.rightButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.mas_offset(-10);
        make.centerY.mas_offset(0);
        make.width.mas_equalTo(20);
        make.height.mas_equalTo(30);
    }];
    
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_offset(0);
        make.left.mas_offset(0);
        make.right.mas_offset(0);
        make.height.mas_equalTo(self.mas_height).offset(0);
    }];   
    
    [self setEnablRightClick:NO];       //default
    [self setFrame:CGRectMake(0,NAVIGATION_BAR_HEIGHT, SCREEN_WIDTH, _viewHeight)];
    [self layoutIfNeeded];
    
    [self.rightButton setImage:[UIImage imageNamed:@"X_icon"] forState:(UIControlStateNormal)];
    self.rightButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
    
    [self.rightButton addTarget:self action:@selector(rightButtonClick:) forControlEvents:(UIControlEventTouchUpInside)];
    
    //test
//    self.rightButton.backgroundColor = [UIColor redColor];
//    self.textLabel.backgroundColor = [UIColor lightGrayColor];
//    self.iconImageView.backgroundColor = themeColor();
//    [self.textLabel setText:@"Not animated to set NeedsDisplay with view commitAnimations."];
}

- (void)dealloc{
    NSLog(@"%s",__func__);
}

#pragma mark - private method
/** 获取 level normal 的window */
+ (UIView *)getViewFromNormalWindow{
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal) {
        NSArray *windows = [UIApplication sharedApplication].windows;
        for (UIWindow *tmpWin in windows) {
            if (tmpWin.windowLevel == UIWindowLevelNormal) {
                window = tmpWin;
                break;
            }
        }
    }
    if (!window && [UIApplication sharedApplication].windows.count) {
        window = [[UIApplication sharedApplication].windows firstObject];
    }
    if (!window){
        @throw [NSException exceptionWithName:@"UIWindow Error" reason:@"Application window is null" userInfo:nil];
    }
    
    return window;
}

/** 根据 Window 获取当前ViewController */
UIViewController *GetViewControllerOfWindow(){
    UIViewController *resultVc = nil;
    UIWindow *window = GetNormalWindow();
    
    if (window) {
        UIView *fontView = [[window subviews] objectAtIndex:0];
        id nextResponder = [fontView nextResponder];
        if ([nextResponder isKindOfClass:[UITabBarController class]]){
            nextResponder = [(UITabBarController *)nextResponder selectedViewController];
        }
        if ([nextResponder isKindOfClass:[UINavigationController class]]) {
            nextResponder = [(UINavigationController *)nextResponder visibleViewController];
        }
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            resultVc = (UIViewController *)nextResponder;
        }else{
            resultVc = window.rootViewController;
        }
    }
    
    return resultVc;
}

/** 根据 View 获取所在ViewController */
UIViewController *GetViewControllerOfView(UIView *view){
    NSInteger num = 0;
    
    if (![view superview] && [view nextResponder]) {
        UIResponder *nextResponder = [view nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)nextResponder;
        }
    }
    
    for (UIView *next = [view superview]; next; next = next.superview) {
        num++;
        if (num >5) {
            break;
        }
        UIResponder *nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

/** 获取 level normal 的window */
UIWindow *GetNormalWindow(void){
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal) {
        NSArray *windows = [UIApplication sharedApplication].windows;
        for (UIWindow *tmpWin in windows) {
            if (tmpWin.windowLevel == UIWindowLevelNormal) {
                window = tmpWin;
                break;
            }
        }
    }
    if (!window && [UIApplication sharedApplication].windows.count) {
        window = [[UIApplication sharedApplication].windows firstObject];
    }
    if (!window){
        @throw [NSException exceptionWithName:@"UIWindow Error" reason:@"Application window is null" userInfo:nil];
    }
    
    return window;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end

